package com.enthal.basicpers

import android.Manifest.permission.ACCESS_NETWORK_STATE
import android.R
import android.annotation.SuppressLint
import android.app.*
import android.content.ActivityNotFoundException
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.net.Uri
import android.os.Build
import android.os.PowerManager
import android.os.Vibrator
import android.provider.Settings
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.annotation.RequiresPermission
import androidx.core.app.NotificationCompat


object RuntimeStatus {
    private var wakeLock: PowerManager.WakeLock? = null

    private var notice_id = 10

    /** 应用是否在白名单中
     *
     */
    @RequiresApi(api = Build.VERSION_CODES.M)
    fun isIgnoringBatteryOptimizations(context: Context): Boolean {
        var isIgnoring = false
        val powerManager =
            context.getSystemService(Service.POWER_SERVICE) as PowerManager?
        if (powerManager != null) {
            isIgnoring = powerManager.isIgnoringBatteryOptimizations(context.packageName)
        }
        return isIgnoring
    }

    // https://www.cnblogs.com/Android-Alvin/p/12465949.html
    @SuppressLint("BatteryLife")
    @RequiresApi(api = Build.VERSION_CODES.M)
    fun requestIgnoreBatteryOptimizations(context: Context) {
        try {
            val intent =
                Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
            intent.data = Uri.parse("package:" +context.packageName)
            context.startActivity(intent)
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }
    }

    fun notificationListenerEnable(context: Context): Boolean {
        val packageName: String = context.packageName
        val flat: String =
            Settings.Secure.getString(context.contentResolver, "enabled_notification_listeners")
        return flat.contains(packageName)
    }

    fun notificationRunning(context: Context):Boolean {
        val thispkg = context.packageName // "com.enthal.basicpers"
        // TODO: use real class name.
        val clsname = "NoticeListenerService"
        return isServiceRunning(context, "$thispkg.$clsname")
    }

    /**
     * 判断某个服务是否正在运行的方法
     * @param serviceName
     * 是包名+服务的类名（例如：net.loonggg.testbackstage.TestService）
     * @return true代表正在运行，false代表服务没有正在运行
     */
    fun isServiceRunning(context: Context, serviceName: String): Boolean {
        val am = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        val services: List<ActivityManager.RunningServiceInfo> = am.getRunningServices(200)
        for (info in services) {
            if (serviceName == info.service.className)
                return true
        }
        return false
    }

    fun vibrate(context: Context) {
        val vibrator =  context.getSystemService(Service.VIBRATOR_SERVICE) as Vibrator
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        //    vibrator.vibrate(VibrationEffect.createOneShot(1000,1), AudioAttributes.USAGE_ALARM)
        } else {
            val pattern = longArrayOf(1000, 1000, 2000, 50)
        //    vibrator.vibrate(pattern, 1);
            vibrator.vibrate(500);
        }
    }

    //获取电源锁，保持该服务在屏幕熄灭时仍然获取CPU时，保持运行
    // https://www.jb51.net/article/111513.htm
    @SuppressLint("InvalidWakeLockTag")
    fun acquireWakeLock(context: Context) {
        if (null == wakeLock) {
            val pm =
                context.getSystemService(Service.POWER_SERVICE) as PowerManager
            wakeLock = pm.newWakeLock(
                PowerManager.PARTIAL_WAKE_LOCK or PowerManager.ON_AFTER_RELEASE,
                "PostLocationService")
            wakeLock?.acquire(10*60*1000L /*10 minutes*/)
        }
    }

    //释放设备电源锁
    // https://www.jb51.net/article/111513.htm
    fun releaseWakeLock() {
        if (null != wakeLock) {
            wakeLock!!.release()
            wakeLock = null
        }
    }

     fun startIndent(context: Context, intent: Intent) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            //android8.0以上通过startForegroundService启动service
            context.startForegroundService(intent)
        } else {
            context.startService(intent)
        }
    }

    // 发送通知
    fun sendTestNotice(context: Context, title:String="Content Title", content: String="Content") {
        val manager =
            context.getSystemService(Service.NOTIFICATION_SERVICE) as NotificationManager?
        val n: Notification = Notification.Builder(context)
            .setSmallIcon(R.mipmap.sym_def_app_icon).setTicker("Astro通知")
            .setContentTitle(title)
            .setContentText(content).setSubText("AstroApp")
            .setWhen(System.currentTimeMillis()).build()
        manager!!.notify(0, n)
    }

    fun sendNotice(context: Context, title:String="Content Title", content: String="Content") {
        val manager =
            context.getSystemService(Service.NOTIFICATION_SERVICE) as NotificationManager?
        manager?.notify(++notice_id, buildNotice(context,title, content))
    }

    fun buildNotice(context: Context, title:String="Content Title", content: String="Content"): Notification? {
        val chId = "TgStartServiceId"
        val ntName = "TgStartServiceName"
        val manager =
            context.getSystemService(Service.NOTIFICATION_SERVICE) as NotificationManager?

        val builder = NotificationCompat.Builder(context, chId)
            .setDefaults(Notification.DEFAULT_ALL)
            .setPriority(Notification.PRIORITY_MAX)
            .setWhen(System.currentTimeMillis())
            .setSmallIcon(R.mipmap.sym_def_app_icon)
            .setTicker("Astro通知")
            .setContentTitle(title)
            .setContentText(content)
            .setContentInfo("Info")
            .setAutoCancel(true)

        //设置Notification的ChannelID,否则不能正常显示
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            builder.setChannelId(chId)
            builder.priority = NotificationManager.IMPORTANCE_HIGH
            val channel = NotificationChannel(chId, ntName,NotificationManager.IMPORTANCE_HIGH)
            channel.description = "Channel description"

            channel.enableLights(true)
            channel.lightColor = Color.RED

            channel.enableVibration(true)
            channel.vibrationPattern = longArrayOf(1000)

            manager?.createNotificationChannel(channel)
        }

        return builder.build()
    }

    // 跳转服务通知的权限界面
    public fun settingsNotice(context: Context):Boolean{
        return try {
            val intent = Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS")
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            context.startActivity(intent)
            true
        } catch (e: ActivityNotFoundException) { //普通情况下找不到的时候需要再特殊处理找一次
            try {
                val intent = Intent()
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                val cn = ComponentName(
                    "com.android.settings",
                    "com.android.settings.Settings\$NotificationAccessSettingsActivity"
                )
                intent.component = cn
                intent.putExtra(":settings:show_fragment", "NotificationAccessSettings")
                context.startActivity(intent)
                return true
            } catch (e1: Exception) {
                e1.printStackTrace()
            }
            Toast.makeText(context, "对不起，您的手机暂不支持", Toast.LENGTH_SHORT).show()
            e.printStackTrace()
            false
        }
    }

    /**
     * 当前连接状态
     */
    @RequiresPermission(ACCESS_NETWORK_STATE)
    fun iNetConnected(context: Context): Boolean {
         val cnnmanager =
            context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val networkCapabilities =
                cnnmanager.getNetworkCapabilities(cnnmanager.activeNetwork)
            if (networkCapabilities != null) {
                return (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
                        || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
                        || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET))
            }
        } else {
            val networkInfo = cnnmanager.activeNetworkInfo
            return networkInfo != null && networkInfo.isConnected
        }
        return false
    }

    fun isWifiConnected(context: Context): Boolean {
        val cnnmanager =
            context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val networkCapabilities =
                cnnmanager.getNetworkCapabilities(cnnmanager.activeNetwork)
            if (networkCapabilities != null) {
                return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
            }
        } else {
            val networkInfo = cnnmanager.activeNetworkInfo
            return networkInfo != null && networkInfo.isConnected && networkInfo.type == ConnectivityManager.TYPE_WIFI
        }
        return false
    }
}